package com.gui.mianshiya.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gui.mianshiya.common.ErrorCode;
import com.gui.mianshiya.exception.BusinessException;
import com.gui.mianshiya.exception.ThrowUtils;
import com.gui.mianshiya.manager.AiManager;
import com.gui.mianshiya.mapper.MultiQuestionMapper;
import com.gui.mianshiya.mapper.MultiQuestionRecordsMapper;
import com.gui.mianshiya.mapper.QuestionBankMapper;
import com.gui.mianshiya.model.dto.multiQuestion.MultiQuestionQueryRequest;
import com.gui.mianshiya.model.entity.MultiQuestion;
import com.gui.mianshiya.model.entity.MultiQuestionRecords;
import com.gui.mianshiya.model.entity.QuestionBank;
import com.gui.mianshiya.model.entity.User;
import com.gui.mianshiya.service.MultiQuestionService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 在線測試題目服務實現類
 */
@Service
@Slf4j
public class MultiQuestionServiceImpl extends ServiceImpl<MultiQuestionMapper, MultiQuestion> implements MultiQuestionService {

    @Resource
    private MultiQuestionMapper multiQuestionMapper;

    @Resource
    private MultiQuestionRecordsMapper multiQuestionRecordsMapper;

    @Resource
    private QuestionBankMapper questionBankMapper;

    @Resource
    private AiManager aiManager;

    @Override
    public Page<MultiQuestion> listMultiQuestionByPage(MultiQuestionQueryRequest multiQuestionQueryRequest) {
        long current = multiQuestionQueryRequest.getCurrent();
        long size = multiQuestionQueryRequest.getPageSize();

        LambdaQueryWrapper<MultiQuestionRecords> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MultiQuestionRecords::getQuestionBankId, multiQuestionQueryRequest.getQuestionBankId());
        wrapper.eq(MultiQuestionRecords::getUserId, multiQuestionQueryRequest.getUserId());
        List<MultiQuestionRecords> multiQuestionRecords = multiQuestionRecordsMapper.selectList(wrapper);
        // 取出已經存在的multiQuestionId集合
        List<Long> existMultiQuestionIds = multiQuestionRecords.stream()
                .map(MultiQuestionRecords::getMultiQuestionId)
                .collect(Collectors.toList());
        // 創建查詢條件
        QueryWrapper<MultiQuestion> queryWrapper = new QueryWrapper<>();
        if (multiQuestionQueryRequest != null) {
            // 根據題庫 ID 查詢
            Long questionBankId = multiQuestionQueryRequest.getQuestionBankId();
            if (ObjectUtils.isNotEmpty(questionBankId)) {
                queryWrapper.eq("questionBankId", questionBankId);
            }
            // 排除已存在的multiQuestionId
            if (existMultiQuestionIds != null && !existMultiQuestionIds.isEmpty()) {
                queryWrapper.notIn("id", existMultiQuestionIds);
            }
        }
        // 計算正確的 current
        // 執行分頁查詢
        Page<MultiQuestion> questionPage = this.page(new Page<>(current, size), queryWrapper);
        return questionPage;
    }

    @Override
    public void validMultiQuestion(MultiQuestion multiQuestion, boolean add) {
        if (multiQuestion == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        String question = multiQuestion.getQuestion();
        String answerA = multiQuestion.getAnswerA();
        String answerB = multiQuestion.getAnswerB();
        String answerC = multiQuestion.getAnswerC();
        String answerD = multiQuestion.getAnswerD();
        String rightAnswer = multiQuestion.getRightAnswer();
        String analysis = multiQuestion.getAnalysis();
        Long score = multiQuestion.getScore();
        Long level = multiQuestion.getLevel();
        Long questionBankId = multiQuestion.getQuestionBankId();

        // 創建時，所有參數不能為空
        if (add) {
            ThrowUtils.throwIf(StringUtils.isAnyBlank(question, answerA, answerB, answerC, answerD, rightAnswer, analysis), ErrorCode.PARAMS_ERROR);
            ThrowUtils.throwIf(score == null || score <= 0, ErrorCode.PARAMS_ERROR, "分數必須大於0");
            ThrowUtils.throwIf(questionBankId == null, ErrorCode.PARAMS_ERROR, "題庫ID不能為空");
            ThrowUtils.throwIf(level == null || level <= 0, ErrorCode.PARAMS_ERROR, "<UNK>0");
        }
        // 有參數則校驗
        if (StringUtils.isNotBlank(question) && question.length() > 1000) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "題目內容過長");
        }
        if (StringUtils.isNotBlank(analysis) && analysis.length() > 2000) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "題目解析過長");
        }
        if (score != null && score <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "分數必須大於0");
        }
    }

    @Override
    public Boolean aiGenerateMultiQuestions(int number, User loginUser, Long questionBankId) {
        if (ObjectUtil.hasEmpty(questionBankId, number, loginUser)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数错误");
        }
        QuestionBank questionBank = questionBankMapper.selectById(questionBankId);
        // 1. 定义系统 Prompt
        String systemPrompt = "你是一位专业的程序员面试官，你要帮我生成 {数量} 道 {方向}面试题，answerA为选项A以此类推 ，analysis要求根据生成的题目内容解析，score根据题目的难度来化算分数 分数分为3类分别为1分，2分，3分，level为题目难度 根据题目的难度来分别设置为1，2，3，要求输出格式如下：\n" +
                "\n" +
                "1. question:\"DNS 服务器和DHCP服务器的作用是（）？\",answerA:\"将IP地址翻译为计算机名，为客户机分配IP地址\",answerB:\"将IP地址翻译为计算机名、解析计算机的MAC地址\",answerC:\"将计算机名翻译为IP地址、为客户机分配IP地址\",answerD:\"将计算机名翻译为IP地址、解析计算机的MAC地址\",rightAnswer:\"C\",analysis:\"解析内容\",score:2\",level:1\" \n" +
                "2. xxxxxx\n" +
                "\n" +
                "除此之外，请不要输出任何多余的内容，不要输出开头、也不要输出结尾，只输出上面的列表。\n" +
                "\n" +
                "接下来我会给你要生成的题目{数量}、以及题目{方向}\n";
        // 2. 拼接用户 Prompt
        String userPrompt = String.format("题目数量：%s, 题目方向：%s", number, questionBank.getTitle());
        // 3. 调用 AI 生成题目
        String answer = aiManager.doChat(systemPrompt, userPrompt);
        ArrayList<MultiQuestion> multiQuestions = new ArrayList<>();
        
        // 將每個問題轉換為JSON格式
        String[] questions = answer.split("\n");
        for (String questionStr : questions) {
            if (questionStr.trim().isEmpty()) {
                continue;
            }
            
            // 移除序號（如 "3. "）
            questionStr = questionStr.replaceAll("^\\d+\\.\\s*", "");
            
            // 將字符串轉換為JSON格式
            String jsonStr = questionStr
                .replace("question:", "\"question\":")
                .replace("answerA:", "\"answerA\":")
                .replace("answerB:", "\"answerB\":")
                .replace("answerC:", "\"answerC\":")
                .replace("answerD:", "\"answerD\":")
                .replace("rightAnswer:", "\"rightAnswer\":")
                .replace("analysis:", "\"analysis\":")
                .replace("score:", "\"score\":")
                .replace("level:", "\"level\":")
                .replace("\"", "\\\"")
                .replace("\\\"", "\"");
            
            try {
                // 使用JSON解析
                ObjectMapper mapper = new ObjectMapper();
                JsonNode node = mapper.readTree("{" + jsonStr + "}");
                
                MultiQuestion question = new MultiQuestion();
                question.setQuestion(node.get("question").asText());
                question.setAnswerA(node.get("answerA").asText());
                question.setAnswerB(node.get("answerB").asText());
                question.setAnswerC(node.get("answerC").asText());
                question.setAnswerD(node.get("answerD").asText());
                question.setRightAnswer(node.get("rightAnswer").asText());
                question.setAnalysis(node.get("analysis").asText());
                question.setScore(Long.parseLong(node.get("score").asText()));
                question.setLevel(Long.parseLong(node.get("level").asText()));
                question.setCreateTime(new Date());
                question.setQuestionBankId(questionBankId);
                question.setSubject(questionBank.getTitle());
                question.setUserId(loginUser.getId());
                multiQuestions.add(question);
            } catch (Exception e) {
                log.error("解析問題失敗: " + questionStr, e);
            }
        }
        boolean b = this.saveBatch(multiQuestions);
        if (!b){
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "保存题目失败");
        }
        return true;
    }
}